package com.dimples.dd.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dimples.dd.common.enums.CommonStatusEnum;
import com.dimples.dd.common.model.Option;
import com.dimples.dd.common.pojo.PageResult;
import com.dimples.dd.system.convert.PostConverter;
import com.dimples.dd.system.mapper.SystemPostMapper;
import com.dimples.dd.system.model.entity.SystemPostDO;
import com.dimples.dd.system.model.form.PostForm;
import com.dimples.dd.system.model.query.PostPageQuery;
import com.dimples.dd.system.model.vo.PostPageVO;
import com.dimples.dd.system.service.SystemPostService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

import static com.dimples.dd.common.exception.BizExceptionUtil.exception;
import static com.dimples.dd.common.exception.ErrorCode.*;

@Service
@RequiredArgsConstructor
public class SystemPostServiceImpl extends ServiceImpl<SystemPostMapper, SystemPostDO> implements SystemPostService {

    private final PostConverter postConvert;

    @Override
    public PageResult<PostPageVO> getPostPage(PostPageQuery queryParams) {
        return this.postConvert.entity2Vo(this.baseMapper.selectPage(queryParams));
    }

    @Override
    public List<Option<Long>> listPostOptions() {
        List<SystemPostDO> list = this.baseMapper.selectList((Collection<Long>) null, Collections.singleton(CommonStatusEnum.ENABLE.getValue()));
        return this.postConvert.entities2Options(list);
    }

    @Override
    public PostForm getPostForm(Long postId) {
        return this.postConvert.entity2Form(this.baseMapper.selectById(postId));
    }

    @Override
    public boolean createPost(PostForm postForm) {
        // 校验正确性
        validatePostForCreateOrUpdate(null, postForm.getName(), postForm.getCode());

        // 插入岗位
        SystemPostDO post = this.postConvert.form2Entity(postForm);
        this.baseMapper.insert(post);
        return true;
    }

    @Override
    public boolean updatePost(PostForm postForm) {
        // 校验正确性
        validatePostForCreateOrUpdate(postForm.getId(), postForm.getName(), postForm.getCode());

        // 更新岗位
        SystemPostDO updateObj = this.postConvert.form2Entity(postForm);
        this.baseMapper.updateById(updateObj);
        return true;
    }

    @Override
    public boolean deletePost(String ids) {
        long[] posts = StrUtil.splitToLong(ids, StrUtil.COMMA);
        for (long postId : posts) {
            // 校验是否存在
            validatePostExists(postId);
            // todo: 还需要删除岗位关联？
            // 删除岗位
            this.baseMapper.deleteById(postId);
        }
        return true;
    }

    private void validatePostForCreateOrUpdate(Long id, String name, String code) {
        // 校验自己存在
        validatePostExists(id);
        // 校验岗位名的唯一性
        validatePostNameUnique(id, name);
        // 校验岗位编码的唯一性
        validatePostCodeUnique(id, code);
    }

    private void validatePostNameUnique(Long id, String name) {
        SystemPostDO post = this.baseMapper.selectByName(name);
        if (post == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的岗位
        if (id == null) {
            throw exception(POST_NAME_DUPLICATE);
        }
        if (!post.getId().equals(id)) {
            throw exception(POST_NAME_DUPLICATE);
        }
    }

    private void validatePostCodeUnique(Long id, String code) {
        SystemPostDO post = this.baseMapper.selectByCode(code);
        if (post == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的岗位
        if (id == null) {
            throw exception(POST_CODE_DUPLICATE);
        }
        if (!post.getId().equals(id)) {
            throw exception(POST_CODE_DUPLICATE);
        }
    }

    private void validatePostExists(Long id) {
        if (id == null) {
            return;
        }
        if (this.baseMapper.selectById(id) == null) {
            throw exception(POST_NOT_FOUND);
        }
    }
}
